/*! ******************************************************************************
 *
 * Created on 2021年9月25日
 *
 * Copyright(c) YuZhou Big Data Laboratory CO.,Ltd, 2022.  All rights reserved.
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

package org.pentaho.di.ui.spoon.navigation.design;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.eclipse.jface.window.DefaultToolTip;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.*;
import org.pentaho.di.core.plugins.PluginInterface;
import org.pentaho.di.core.plugins.PluginRegistry;
import org.pentaho.di.core.plugins.PluginTypeInterface;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.ui.core.ConstUI;
import org.pentaho.di.ui.spoon.Spoon;
import org.pentaho.di.ui.spoon.navigation.Bundle;
import org.pentaho.di.ui.spoon.navigation.design.classification.Classification;
import org.pentaho.di.ui.spoon.navigation.design.classification.category.Category;
import org.pentaho.di.ui.spoon.navigation.design.classification.plugin.*;
import org.pentaho.di.ui.util.PinyinUtils;
import org.pentaho.di.ui.util.StringUtils;
import org.yzbdl.lanius.authorize.verification.LicenseVerification;
import org.yzbdl.lanius.core.plugins.metastore.LdrCategoryEntity;
import org.yzbdl.lanius.core.plugins.metastore.LdrClassificationEntity;
import org.yzbdl.lanius.core.plugins.metastore.LdrPluginEntity;
import org.yzbdl.lanius.core.plugins.metastore.LogicType;
import org.yzbdl.lanius.core.plugins.service.CategoryService;
import org.yzbdl.lanius.core.plugins.service.ClassificationService;
import org.yzbdl.lanius.core.plugins.service.PluginService;

import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 抽象树
 *
 * @author hs@yzbdl.ac.cn
 * @version 1.0
 * @date 2019-06-11 10:51
 */
public abstract class AbstractTree {

    /**
     * 将加载出来的Plugin放入一个静态MAP
     */
    public static Map<String, Set<LaniusPluginTreeItem>> rtPluginTreeItemMap = Maps.newConcurrentMap();

    private ClassificationService classificationService = ClassificationService.getInstance();
    // private CategoryService categoryService = CategoryService.getInstance();
    private PluginService pluginService = PluginService.getInstance();
    // private UserService userService = UserService.getInstance();
    private CategoryService categoryService = CategoryService.getInstance();

    private Spoon spoon;

    private LaniusClassExpandBar expandBar;

    private DefaultToolTip toolTip;

    /**
     * 常用
     */
    private Classification commonlyEntity;

    /**
     * 自定义
     */
    private List<Classification> customizeEntities = Lists.newArrayList();

    /**
     * 默认(本地)
     */
    private Classification defaultEntity;

    // /**
    // * 云端
    // */
    // private Classification marketEntity;

    public AbstractTree(Spoon spoon, FormData layout) {
        super();
        this.spoon = spoon;
        expandBar = new LaniusClassExpandBar(spoon, SWT.V_SCROLL, layout);

        toolTip = new DefaultToolTip(expandBar, ToolTip.RECREATE, true);
        toolTip.setRespectMonitorBounds(true);
        toolTip.setRespectDisplayBounds(true);
        toolTip.setPopupDelay(350);
        toolTip.setHideDelay(5000);
        toolTip.setShift(new org.eclipse.swt.graphics.Point(ConstUI.TOOLTIP_OFFSET, ConstUI.TOOLTIP_OFFSET));
    }

    /**
     * 刷新整个插件树
     */
    protected void render() {
        dispose();
        buildAllClassification();
    }

    /**
     * 刷新指定插件
     *
     * @param plugin
     */
    protected void render(Plugin plugin) {
        LdrPluginEntity entity = plugin.getPluginEntity();
        String key = entity.getPluginTypeClass() + "_" + entity.getPluginId() + "_" + entity.getVersion();
        Set<LaniusPluginTreeItem> treeItems = AbstractTree.rtPluginTreeItemMap.get(key);
        for (LaniusPluginTreeItem treeItem : treeItems) {
            if (treeItem.isDisposed()) {
            } else {
                treeItem.setText(plugin.getName());
                treeItem.setImage(plugin.getImage());
                treeItem.setPluginEntity(entity);
            }
        }
    }

    private void buildAllClassification() {
        // 处于搜索状态, 则不显示常用和自定义，只显示本地和云端即可，防止搜索出重复的插件
        if (!isFilterEnabled()) {
            // 构建常用分类
            commonlyEntity = buildCommonly(getClassType());
            // 构建自定义分类
            customizeEntities = buildCustomize(getClassType());
        }

        // 构建默认分类
        defaultEntity = buildDefault(getClassType());
        // 构建商店（云端）分类
        // marketEntity = buildMarket(getClassType());
    }

    // /**
    // * 检查是否为免费插件或者收费插件//是否可以直接下载
    // *
    // * @throws IOException
    // */
    // protected boolean checkOpenType(String id) throws IOException {
    // if (Spoon.getInstance().getLoginSwt().getLoginUtil().getCookie() == null) {
    // spoon.login(Const.MARKET_SERVER_ADDRESS);
    // }
    // URL url = new URL(Const.MARKET_SERVER_ADDRESS + "/plugin/details/addDownload?id=" + Integer.parseInt(id));
    // // 1.通过调用URL对象的openConnection()方法来创建URLConnection对象
    // HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    // // 2.设置URLConnection的参数和普通请求属性
    // conn.setConnectTimeout(5 * 1000);
    // conn.setRequestMethod("GET");
    // conn.setRequestProperty("Charset", "UTF-8");
    // conn.setRequestProperty("User-Agent", "LaniusDesign");
    // conn.setRequestProperty("Cookie", Spoon.getInstance().getLoginSwt().getLoginUtil().getCookie());
    // int responseCode = conn.getResponseCode();
    // if (responseCode == 200) {
    // return true;
    // } else {
    // return false;
    // }
    // }

    /**
     * 返回插件类型(JobEntryPluginType, StepPluginType)
     *
     * @return
     */
    protected abstract Class<? extends PluginTypeInterface> getClassType();

    /**
     * 是否显示
     *
     * @return
     */
    protected boolean isShow() {
        return getExpandBar().getVisible();
    }

    /**
     * 显示视图
     */
    protected void show() {
        getExpandBar().setVisible(true);
    }

    /**
     * 隐藏视图
     */
    protected void hide() {
        getExpandBar().setVisible(false);
    }

    /**
     * 回收视图资源
     */
    protected void dispose() {
        for (Control control : getExpandBar().getChildren()) {
            control.dispose();
        }
        for (LaniusClassExpandItem item : getExpandBar().getItems()) {
            item.dispose();
        }
    }

    /**
     * 常用分类栏目
     *
     * @param pluginTypeClass
     * @return
     */
    protected Classification buildCommonly(Class<? extends PluginTypeInterface> pluginTypeClass) {

        // FuncType funcType = Func2PluginTypeClass.getBy(pluginTypeClass);

        List<LdrClassificationEntity> commonClses = classificationService.getAll(pluginTypeClass, LogicType.COMMONLY);
        if (commonClses != null && commonClses.size() == 1) {
            LdrClassificationEntity commonCls = commonClses.get(0);
            Classification classification = buildClassification(commonCls);
            Set<Plugin> plugins = new LinkedHashSet<>();

            List<LdrPluginEntity> pluginEntities = pluginService.getCommonlyPlugins(pluginTypeClass);
            for (LdrPluginEntity ldrPluginEntity : pluginEntities) {
                // 不显示不可用的树
                if (!ldrPluginEntity.getIsValid()) {
                    continue;
                }
                plugins.addAll(buildPluginWithVersion(pluginTypeClass, ldrPluginEntity, classification));
            }
            classification.setPlugins(plugins);

            if (isFilterEnabled() && classification.isEmpty()) {
                classification.dispose();
                return classification;
            }
            return classification;
        }
        return null;
    }

    /**
     * 自定义分类栏目
     *
     * @param pluginTypeClass
     * @return
     */
    protected List<Classification> buildCustomize(Class<? extends PluginTypeInterface> pluginTypeClass) {
        List<Classification> classifications = new ArrayList<>();

        // FuncType funcType = Func2PluginTypeClass.getBy(pluginTypeClass);
        List<LdrClassificationEntity> customClses = classificationService.getAll(pluginTypeClass, LogicType.CUSTOMIZE);

        for (LdrClassificationEntity customCls : customClses) {
            Classification classification = buildClassification(customCls);
            Set<Category> categories = new LinkedHashSet<>();

            List<LdrCategoryEntity> ldrCategoryEntityList = categoryService.getAllByClassificationId(customCls.getId());

            for (LdrCategoryEntity ldrCategoryEntity : ldrCategoryEntityList) {
                Category category = buildCategory(ldrCategoryEntity, classification);
                Set<Plugin> pluginLinkedHashSet = new LinkedHashSet<>();
                // 需要修改
                List<LdrPluginEntity> ldrPluginEntityList = pluginService.getAllByCategoryId(ldrCategoryEntity.getId());
                for (LdrPluginEntity ldrPluginEntity : ldrPluginEntityList) {
                    List<Plugin> pluginVerions = buildPluginWithVersion(pluginTypeClass, ldrPluginEntity, category);
                    pluginLinkedHashSet.addAll(pluginVerions);
                }

                // 搜索的时候，去掉空的分组，因为查看起来不方便
                if (isFilterEnabled() && category.isEmpty()) {
                    category.dispose();
                    continue;
                }

                category.setPlugins(pluginLinkedHashSet);
                categories.add(category);
            }
            classification.setCategories(categories);
            // 搜索的时候，去掉空的分类，因为查看起来不方便
            if (isFilterEnabled() && classification.isEmpty()) {
                classification.dispose();
                continue;
            }
            classifications.add(classification);
        }
        return classifications;
    }

    // /**
    // * 构建默认分类
    // *
    // * @param pluginTypeClass 插件类型
    // * @return
    // */
    // protected Classification buildDefault(Class<? extends PluginTypeInterface> pluginTypeClass) {
    // List<ClassificationEntity> defaultClses = classificationService.getAll(pluginTypeClass, LogicType.DEFAULT);
    // if (defaultClses != null && defaultClses.size() == 1) {
    // ClassificationEntity defaultCls = defaultClses.get(0);
    // Classification classification = buildClassification(defaultCls);
    //
    // Set<Category> categories = new LinkedHashSet<>();
    // List<CategoryEntity> categoryEntities =
    // categoryService.getAllByClassificationId(defaultCls.getId());
    // for (CategoryEntity categoryEntity : categoryEntities) {
    // Category category = buildCategory(categoryEntity, classification);
    //
    // Set<Plugin> plugins = new LinkedHashSet<>();
    // List<PluginEntity> pluginEntities = pluginService.getAllByCategoryId(categoryEntity.getId());
    // for (PluginEntity pluginEntity : pluginEntities) {
    // // 不显示不可用的树
    // if(!pluginEntity.getIsValid()){
    // continue;
    // }
    // plugins.addAll(buildPlugin(pluginTypeClass, pluginEntity, category, false));
    // }
    // category.setPlugins(plugins);
    //
    // // 搜索的时候，去掉空的分组，因为查看起来不方便
    // if (isFilterEnabled() && category.isEmpty()) {
    // category.dispose();
    // continue;
    // }
    // categories.add(category);
    // }
    //
    // classification.setCategories(categories);
    //
    // // 搜索的时候，去掉空的分类，因为查看起来不方便
    // if (isFilterEnabled() && classification.isEmpty()) {
    // classification.dispose();
    // return classification;
    // }
    // return classification;
    // }
    // return null;
    // }

    /**
     * 构建默认分类
     *
     * @param pluginTypeClass 插件类型
     * @return
     */
    protected Classification buildDefault(Class<? extends PluginTypeInterface> pluginTypeClass) {
        LdrClassificationEntity defaultCls = classificationService.getDefault(pluginTypeClass);
        if (defaultCls != null) {
            // 拼音搜索过滤
            defaultCls = getFilterDefault(defaultCls);
            Classification classification = buildClassification(defaultCls);

            Set<Category> categories = new LinkedHashSet<>();
            List<LdrCategoryEntity> categoryEntities = defaultCls.getCategoryEntities();
            List<String> categoryList = Lists.newArrayList();
            for (LdrCategoryEntity ldrCategoryEntity : categoryEntities) {
                Category category = buildCategory(ldrCategoryEntity, classification);
                Set<Plugin> plugins = new LinkedHashSet<>();
                List<LdrPluginEntity> pluginEntities = ldrCategoryEntity.getPluginEntities();
                List<String> pluginIdList = Lists.newArrayList();
                for (LdrPluginEntity pluginFolder : pluginEntities) {
                    if (!pluginIdList.contains(pluginFolder.getPluginId())) {
                        List<LdrPluginEntity> pluginVersions =
                                pluginService.getPluginVersions(pluginFolder.getPluginId());
                        // 非商业版客户端不显示商业版插件
                        if (!LicenseVerification.ACTIVE_ENTERPRISE_EDITION && pluginFolder.getEnterprise()) {
                            continue;
                        }
                        // 查询插件的所有版本
                        for (LdrPluginEntity ldrPluginEntity : pluginVersions) {
                            // 不显示不可用的树插件无效
                            if (!ldrPluginEntity.getIsValid()) {
                                continue;
                            }
                            plugins.addAll(buildPluginWithVersion(pluginTypeClass, ldrPluginEntity, category));
                        }
                        pluginIdList.add(pluginFolder.getPluginId());
                    }
                }

                category.setPlugins(plugins);

                // 搜索或商业版的时候，去掉空的分组，因为查看起来不方便
                if ((isFilterEnabled() || !LicenseVerification.ACTIVE_ENTERPRISE_EDITION) && category.isEmpty()) {
                    category.dispose();
                    continue;
                }
                categories.add(category);
                categoryList.add(ldrCategoryEntity.getName());

            }

            classification.setCategories(categories);

            // 搜索的时候，去掉空的分类，因为查看起来不方便
            if (isFilterEnabled() && classification.isEmpty()) {
                classification.dispose();
                return classification;
            }
            return classification;
        }
        return null;
    }

    /**
     * 构建默认分组 包含目录层级
     *
     * @param pluginTypeClass 插件类型
     * @return
     */
    protected Classification buildDefaultGroup(Class<? extends PluginTypeInterface> pluginTypeClass) {
        LdrClassificationEntity defaultCls = classificationService.getDefault(pluginTypeClass);
        if (defaultCls != null) {
            // 拼音搜索过滤
            defaultCls = getFilterDefault(defaultCls);
            Classification classification = buildClassification(defaultCls);

            Set<Category> categories = new LinkedHashSet<>();
            List<LdrCategoryEntity> categoryEntities = defaultCls.getCategoryEntities();
            List<String> categoryList = Lists.newArrayList();
            for (LdrCategoryEntity ldrCategoryEntity : categoryEntities) {
                Category category = buildCategory(ldrCategoryEntity, classification);
                Set<Plugin> plugins = new LinkedHashSet<>();
                List<LdrPluginEntity> pluginEntities = ldrCategoryEntity.getPluginEntities();
                List<String> pluginIdList = Lists.newArrayList();
                for (LdrPluginEntity pluginFolder : pluginEntities) {
                    if (!pluginIdList.contains(pluginFolder.getPluginId())) {
                        PluginVersion pluginVersion = buildPluginFolder(pluginFolder, category);
                        List<LdrPluginEntity> pluginVersions =
                                pluginService.getPluginVersions(pluginFolder.getPluginId());
                        // 非商业版客户端不显示商业版插件
                        if (!LicenseVerification.ACTIVE_ENTERPRISE_EDITION && pluginFolder.getEnterprise()) {
                            continue;
                        }
                        // 查询插件的所有版本
                        for (LdrPluginEntity ldrPluginEntity : pluginVersions) {
                            // 不显示不可用的树插件无效
                            if (!ldrPluginEntity.getIsValid()) {
                                continue;
                            }
                            plugins.addAll(buildPluginWithVersion(pluginTypeClass, ldrPluginEntity, pluginVersion));
                        }
                        pluginIdList.add(pluginFolder.getPluginId());
                    }
                }

                category.setPlugins(plugins);

                // 搜索或商业版的时候，去掉空的分组，因为查看起来不方便
                if ((isFilterEnabled() || !LicenseVerification.ACTIVE_ENTERPRISE_EDITION) && category.isEmpty()) {
                    category.dispose();
                    continue;
                }
                categories.add(category);
                categoryList.add(ldrCategoryEntity.getName());

            }

            classification.setCategories(categories);

            // 搜索的时候，去掉空的分类，因为查看起来不方便
            if (isFilterEnabled() && classification.isEmpty()) {
                classification.dispose();
                return classification;
            }
            return classification;
        }
        return null;
    }

    /**
     * 判断是否匹配搜索（搜索栏为空字符串时，全部匹配）
     *
     * @param string 插件名称
     * @return true 显示; false 不显示
     */
    protected boolean filterMatch(String string) {
        if (Utils.isEmpty(string)) {
            return true;
        }

        String filter = getSpoon().selectionFilter.getText();
        if (Utils.isEmpty(filter)) {
            return true;
        }
        PinyinUtils pinyinUtils = new PinyinUtils();
        String pinyin = pinyinUtils.getPinyin(string).toLowerCase();
        String pinyinFilter = pinyinUtils.getPinyin(filter).toLowerCase();
        String fisrtSpell = pinyinUtils.getFisrtSpell(string).toLowerCase();
        try {
            if (string.matches(filter)) {
                return true;
            }
            if (pinyin.matches(pinyinFilter) | fisrtSpell.matches(pinyinFilter)) {
                return true;
            }
        } catch (Exception e) {
        }
        return pinyin.toUpperCase().contains(pinyinFilter.toUpperCase())
                | fisrtSpell.toUpperCase().contains(pinyinFilter.toUpperCase());
    }

    /**
     * 过滤拼音关键
     *
     * @param ldrClassificationEntity 分组实体
     * @return 结果
     */
    protected LdrClassificationEntity getFilterDefault(LdrClassificationEntity ldrClassificationEntity) {
        List<LdrCategoryEntity> listLdrCategoryEntity = ldrClassificationEntity.getCategoryEntities();
        List<LdrCategoryEntity> listLdrCategoryEntityFilter = new ArrayList<>();
        for (LdrCategoryEntity ldrCategoryEntity : listLdrCategoryEntity) {
            List<LdrPluginEntity> listLdrPluginEntity = ldrCategoryEntity.getPluginEntities();
            List<LdrPluginEntity> listNew = listLdrPluginEntity.stream()
                    .filter((LdrPluginEntity m) -> filterMatch(m.getName())).collect(Collectors.toList());
            ldrCategoryEntity.setPluginEntities(listNew);
            listLdrCategoryEntityFilter.add(ldrCategoryEntity);
        }
        ldrClassificationEntity.setCategoryEntities(listLdrCategoryEntityFilter);
        return ldrClassificationEntity;
    }

    // /***
    // * @description 云端插件
    // *
    // * @return
    // * @throws Exception
    // */
    // protected Classification buildMarket(Class<? extends PluginTypeInterface> pluginTypeClass) {
    // ClassificationEntity marketCls = classificationService.getMarket(pluginTypeClass);
    //
    // if (marketCls != null) {
    // Classification classification = buildClassification(marketCls);
    // Set<Category> categories = new LinkedHashSet<>();
    //
    // List<CategoryEntity> categoryEntities = marketCls.getCategoryEntities();
    // for (CategoryEntity categoryEntity : categoryEntities) {
    // Category category = buildCategory(categoryEntity, classification);
    //
    // Set<Plugin> plugins = new LinkedHashSet<>();
    // List<PluginEntity> pluginEntities = categoryEntity.getPluginEntities();
    //
    // for (PluginEntity pluginEntity : pluginEntities) {
    // // 不显示不可用的树
    // if (!pluginEntity.getIsValid()) {
    // continue;
    // }
    // plugins.addAll(buildPlugin(pluginTypeClass, pluginEntity, category, true));
    // }
    //
    // category.setPlugins(plugins);
    //
    // // 搜索的时候，去掉空的分组，因为查看起来不方便
    // if (isFilterEnabled() && category.isEmpty()) {
    // category.dispose();
    // continue;
    // }
    // categories.add(category);
    // }
    // classification.setCategories(categories);
    //
    // // 搜索的时候，去掉空的分类，因为查看起来不方便
    // if (isFilterEnabled() && classification.isEmpty()) {
    // classification.dispose();
    // return classification;
    // }
    // return classification;
    // }
    // return null;
    // }

    /**
     * 构建分类
     *
     * @param ldrClassificationEntity
     * @return
     */
    private Classification buildClassification(LdrClassificationEntity ldrClassificationEntity) {
        Classification classification = new Classification(getSpoon(), toolTip, expandBar, ldrClassificationEntity);
        return classification;
    }

    /**
     * 构建分组
     *
     * @param ldrCategoryEntity
     * @param parent
     * @return
     */
    private Category buildCategory(LdrCategoryEntity ldrCategoryEntity, Bundle parent) {
        Category category = new Category(parent, ldrCategoryEntity);
        return category;
    }

    /**
     * 构建插件目录
     *
     * @param plugin
     * @param parent
     * @return
     */
    private PluginVersion buildPluginFolder(LdrPluginEntity plugin, Bundle parent) {
        PluginVersionEntity pluginVersionEntity = new PluginVersionEntity();
        pluginVersionEntity.setName(plugin.getName());
        PluginVersion pluginFolder = new PluginVersion(parent, pluginVersionEntity);
        return pluginFolder;
    }

    private void setTextAndImages(Plugin plugin) {
        LaniusPluginTreeItem treeItem = plugin.getTreeItem();
        if (treeItem != null) {
            String destText = treeItem.getDestText();
            if (StringUtils.isNotBlank(destText)) {
                treeItem.setText(destText);
            }
            Image destImage = treeItem.getDestImage();
            if (destImage != null) {
                treeItem.setImage(destImage);
            }
        }
    }

    private void setVersionTextAndImages(Plugin plugin) {
        LaniusPluginTreeItem treeItem = plugin.getTreeItem();
        if (treeItem != null) {
            String destText = treeItem.getDestText();
            if (StringUtils.isNotBlank(destText)) {
                if (plugin.getPluginEntity().getVersion().equals("none")) {
                    treeItem.setText("默认");
                } else {
                    treeItem.setText(plugin.getPluginEntity().getVersion());
                }
            }
            Image destImage = treeItem.getDestImage();
            if (destImage != null) {
                treeItem.setImage(destImage);
            }
        }
    }

    private void setNameAndVersionAndImages(Plugin plugin) {
        LaniusPluginTreeItem treeItem = plugin.getTreeItem();
        if (treeItem != null) {
            String destText = treeItem.getDestText();
            if (StringUtils.isNotBlank(destText)) {
                if (plugin.getPluginEntity().getVersion().equals("none")) {
                    treeItem.setText(destText);
                } else {
                    treeItem.setText(new StringBuffer(destText).append(" v")
                            .append(plugin.getPluginEntity().getVersion()).toString());
                }
            }
            Image destImage = treeItem.getDestImage();
            if (destImage != null) {
                treeItem.setImage(destImage);
            }
        }
    }

    /**
     * 过滤是否启用 ,启用过滤则展开所有的Tree并且去掉为空的分组
     *
     * @return true 启用; false 停用
     */
    private boolean isFilterEnabled() {
        String filter = spoon.selectionFilter.getText();
        if (Utils.isEmpty(filter)) {
            return false;
        }
        return true;
    }

    public void resetExpandByEntity() {
        for (ExpandItem item : getExpandBar().getItems()) {
            if (item instanceof LaniusClassExpandItem) {
                LdrClassificationEntity entity = ((LaniusClassExpandItem) item).getClassificationEntity();
                item.setExpanded(entity.getExpanded());
            }
        }
        if (commonlyEntity != null) {
            tidyTree(commonlyEntity.getTree(), null);
        }
        for (Classification c : customizeEntities) {
            tidyTree(c.getTree(), null);
        }
        if (defaultEntity != null) {
            tidyTree(defaultEntity.getTree(), null);
        }
        // if (marketEntity != null) {
        // tidyTree(this.marketEntity.getTree(), null);
        // }
    }

    protected void expandAll() {
        for (ExpandItem item : getExpandBar().getItems()) {
            item.setExpanded(true);
        }
        if (commonlyEntity != null) {
            tidyTree(commonlyEntity.getTree(), true);
        }
        for (Classification c : customizeEntities) {
            tidyTree(c.getTree(), true);
        }
        if (defaultEntity != null) {
            tidyTree(defaultEntity.getTree(), true);
        }
        // if (this.marketEntity != null) {
        // tidyTree(this.marketEntity.getTree(), true);
        // }
    }

    protected void collapseAll() {
        for (ExpandItem item : getExpandBar().getItems()) {
            item.setExpanded(false);
        }
        if (commonlyEntity != null) {
            tidyTree(commonlyEntity.getTree(), false);
        }
        for (Classification c : customizeEntities) {
            tidyTree(c.getTree(), false);
        }
        if (defaultEntity != null) {
            tidyTree(defaultEntity.getTree(), false);
        }
        // if (this.marketEntity != null) {
        // tidyTree(this.marketEntity.getTree(), false);
        // }
    }

    // private void tidyBranches(TreeItem[] items, Boolean expand) {
    // for (TreeItem item : items) {
    // item.setExpanded(expand);
    // tidyBranches(item.getItems(), expand);
    // }
    // }

    private void tidyTree(LaniusClassTree tree, Boolean expand) {
        if (tree != null && !tree.isDisposed()) {
            tidyBranches(tree.getItems(), expand);
        }
    }

    private void tidyBranches(TreeItem[] items, Boolean expand) {
        for (TreeItem item : items) {
            if (expand == null) {
                if (item instanceof LaniusCategoryTreeItem) {
                    LdrCategoryEntity entity = ((LaniusCategoryTreeItem) item).getCategoryEntity();
                    item.setExpanded(entity.getExpanded());
                }
                if (item instanceof LaniusPluginVersionTreeItem) {
                    PluginVersionEntity entity = ((LaniusPluginVersionTreeItem) item).getPluginVersionEntity();
                    item.setExpanded(entity.getExpanded());
                }
            } else {
                item.setExpanded(expand);
            }
            tidyBranches(item.getItems(), expand);
        }
    }

    public Spoon getSpoon() {
        return spoon;
    }

    public LaniusClassExpandBar getExpandBar() {
        return expandBar;
    }

    /**
     * 检查插件是否存在, 存在则返回true, 不存在返回false
     *
     * @param pluginType
     * @param pluginStrId
     * @return
     */
    private boolean checkPluginExists(Class<? extends PluginTypeInterface> pluginType, String pluginStrId,
                                      String version) {
        PluginInterface pluginInterface = PluginRegistry.getInstance().getPlugin(pluginType, pluginStrId, version);
        return pluginInterface != null;
    }

    private void addToRtPluginMap(Plugin plugin) {
        LdrPluginEntity ldrPluginEntity = plugin.getPluginEntity();
        StringBuffer key = new StringBuffer();
        key.append(ldrPluginEntity.getPluginTypeClass() + "_" + ldrPluginEntity.getPluginId() + "_"
                + ldrPluginEntity.getVersion());
        // if (rtPluginMap.containsKey(key.toString())) {
        // Set<Plugin> plugins = rtPluginMap.get(key.toString());
        // plugins.add(plugin);
        // } else {
        // Set<Plugin> plugins = Sets.newConcurrentHashSet();
        // plugins.add(plugin);
        // rtPluginMap.put(key.toString(), plugins);
        // }

        if (AbstractTree.rtPluginTreeItemMap.containsKey(key.toString())) {
            Set<LaniusPluginTreeItem> treeItems = AbstractTree.rtPluginTreeItemMap.get(key.toString());
            LaniusPluginTreeItem item = plugin.getTreeItem();
            if (null != item) {
                treeItems.add(item);
            }
        } else {
            Set<LaniusPluginTreeItem> treeItems = Sets.newConcurrentHashSet();
            LaniusPluginTreeItem item = plugin.getTreeItem();
            if (null != item) {
                treeItems.add(item);
            }
            AbstractTree.rtPluginTreeItemMap.put(key.toString(), treeItems);
        }

    }

    /**
     * 构建插件
     *
     * @param pluginTypeClass
     * @param ldrPluginEntity
     * @param parent
     * @return
     */
    private List<Plugin> buildPlugin(Class<? extends PluginTypeInterface> pluginTypeClass,
                                     LdrPluginEntity ldrPluginEntity, Bundle parent) {
        List<Plugin> plugins = new ArrayList<>();
        if (checkPluginExists(pluginTypeClass, ldrPluginEntity.getPluginId(), ldrPluginEntity.getVersion())) {
            // 如果插件非云端插件，并且在本地存在
            String pluginStrId = ldrPluginEntity.getPluginId();
            // 对作业 SPECIAL插件进行特殊处理
            if ("SPECIAL".equals(pluginStrId)) {
                // Job Start
                Plugin startPlugin = new JobStartPlugin(parent, ldrPluginEntity);
                setTextAndImages(startPlugin);
                addToRtPluginMap(startPlugin);
                if (startPlugin.isNotNull()) {
                    plugins.add(startPlugin);
                }
            } else if ("DummyJob".equals(pluginStrId)) {
                // Job Dummy
                Plugin dummyPlugin = new JobDummyPlugin(parent, ldrPluginEntity);
                setTextAndImages(dummyPlugin);
                addToRtPluginMap(dummyPlugin);
                if (dummyPlugin.isNotNull()) {
                    plugins.add(dummyPlugin);
                }
            } else {
                Plugin plugin = new Plugin(parent, ldrPluginEntity);
                setTextAndImages(plugin);
                addToRtPluginMap(plugin);
                if (plugin.isNotNull()) {
                    plugins.add(plugin);
                }
            }
        }
        return plugins;
    }

    /**
     * 构建插件 显示版本号
     *
     * @param pluginTypeClass
     * @param ldrPluginEntity
     * @param parent
     * @return
     */
    private List<Plugin> buildPluginWithVersion(Class<? extends PluginTypeInterface> pluginTypeClass,
                                                LdrPluginEntity ldrPluginEntity, Bundle parent) {
        List<Plugin> plugins = new ArrayList<>();
        if (checkPluginExists(pluginTypeClass, ldrPluginEntity.getPluginId(), ldrPluginEntity.getVersion())) {
            // 如果插件非云端插件，并且在本地存在
            String pluginStrId = ldrPluginEntity.getPluginId();
            // pluginEntity.setName(
            // new StringBuffer(pluginEntity.getName()).append(" v").append(pluginEntity.getVersion()).toString());
            // 对作业 SPECIAL插件进行特殊处理
            if ("SPECIAL".equals(pluginStrId)) {
                // Job Start
                Plugin startPlugin = new JobStartPlugin(parent, ldrPluginEntity);
                setNameAndVersionAndImages(startPlugin);
                addToRtPluginMap(startPlugin);
                if (startPlugin.isNotNull()) {
                    plugins.add(startPlugin);
                }
            } else if ("DummyJob".equals(pluginStrId)) {
                // Job Dummy
                Plugin dummyPlugin = new JobDummyPlugin(parent, ldrPluginEntity);
                setNameAndVersionAndImages(dummyPlugin);
                addToRtPluginMap(dummyPlugin);
                if (dummyPlugin.isNotNull()) {
                    plugins.add(dummyPlugin);
                }
            } else {
                Plugin plugin = new Plugin(parent, ldrPluginEntity);
                setNameAndVersionAndImages(plugin);
                addToRtPluginMap(plugin);
                if (plugin.isNotNull()) {
                    plugins.add(plugin);
                }
            }
        }
        return plugins;
    }

    // /**
    // * 构建插件不显示名称
    // * @param pluginTypeClass
    // * @param pluginEntity
    // * @param parent
    // * @return
    // */
    // private List<Plugin> buildPluginVersionWithNotName(Class<? extends PluginTypeInterface> pluginTypeClass,
    // PluginEntity pluginEntity, Bundle parent) {
    // List<Plugin> plugins = new ArrayList<>();
    // if (checkPluginExists(pluginTypeClass, pluginEntity.getPluginId(), pluginEntity.getVersion())) {
    // // 如果插件非云端插件，并且在本地存在
    // String pluginStrId = pluginEntity.getPluginId();
    // // 对作业 SPECIAL插件进行特殊处理
    // if ("SPECIAL".equals(pluginStrId)) {
    // // Job Start
    // Plugin startPlugin = new JobStartPlugin(parent, pluginEntity);
    // setVersionTextAndImages(startPlugin);
    // addToRtPluginMap(startPlugin);
    // if (startPlugin.isNotNull()) {
    // plugins.add(startPlugin);
    // }
    // } else if ("DummyJob".equals(pluginStrId)) {
    // // Job Dummy
    // Plugin dummyPlugin = new JobDummyPlugin(parent, pluginEntity);
    // setVersionTextAndImages(dummyPlugin);
    // addToRtPluginMap(dummyPlugin);
    // if (dummyPlugin.isNotNull()) {
    // plugins.add(dummyPlugin);
    // }
    // } else {
    // Plugin plugin = new Plugin(parent, pluginEntity);
    // setVersionTextAndImages(plugin);
    // addToRtPluginMap(plugin);
    // if (plugin.isNotNull()) {
    // plugins.add(plugin);
    // }
    // }
    // }
    // return plugins;
    // }

}